<script setup lang="ts">
// base
import { nextTick, onBeforeUnmount, reactive, useAttrs, watch } from 'vue'
import { onMounted, onUnmounted, ref, VNode, createVNode, render, computed } from 'vue'
import { ElMessage, ElCard, ElButton, ElProgress, ElInputNumber, ElDatePicker, ElLoading, ElDialog } from 'element-plus'
import { VideoPlay, Refresh, VideoPause, DArrowRight, DArrowLeft } from '@element-plus/icons-vue'
//ol
// import { Point, Polygon, Circle as gCircle, LineString } from 'ol/geom'
import { Point } from 'ol/geom'
import { Style, Fill, Stroke, Text, Circle, Icon } from 'ol/style'
import { Map, View, Feature } from 'ol'
import layerVector from 'ol/layer/Vector'
import Cluster from 'ol/source/Cluster'
import Overlay from 'ol/Overlay'
import LineString from 'ol/geom/LineString'
import sourceVector from 'ol/source/Vector'
import { gdMap, browserLocal } from '@/utils/gps/amaputil'
import { computeIcon } from '@/utils/gps/iconTransform'
import poly from '@/assets/poly.png'
//tools
import { gpsbus, rtcbus } from '@/utils/gps/event'
import { createLayers2, createMap, getMap, setMap } from '@/utils/ol/maptools'
import { wsg2mapcoor } from '@/utils/gps/maptransform'
import { Device } from '@/interface/device'
import { computeSubTitle, timeFormat } from '@/utils/gps/format'
import { useGetTrackPosApi } from '@/api/gps/gps'
import { IsPtInPoly } from '@/utils/gps/inside'
import moment from 'moment/moment'
//image
import startIconPng from '@/assets/gps/start_icon.png'
import endIconPng from '@/assets/car/end_icon.png'
import carbluePng from '@/assets/car/car_blue.png'
import stopCar from '@/assets/gps/stop_icon.png'
import { storeToRefs } from 'pinia'
import { useTrackStore } from '@/store/gps/track'
const trackStore = useTrackStore()

// const { gpsTrackData, gpsTrackState, curPos } = storeToRefs(trackStore)

const props = defineProps({
  plateNum: {
    type: String,
    required: true
  },
  control: {
    type: Boolean,
    default: true
  }
})

// const emits = defineEmits(['close'])

// let layers = createLayers2()
// const ctx = useAttrs()
// console.log(moment().format('YYYY-MM-DD HH:mm:ss'))
let demo: any = null
// const dateRange = ref<any>([moment().subtract(1, 'day').format('YYYY-MM-DD HH:mm:ss'), moment().format('YYYY-MM-DD HH:mm:ss')])
const record = reactive<{ position: any[]; travelPath: any[]; stopPosition: any[] }>({
  position: [],
  travelPath: [],
  stopPosition: []
})

const openMap = ref<Map>()
const vectorLayer = ref<layerVector<any>>()
const iconLayer = ref()
const carSource = ref()
let carFeature: Feature
// 播放速率
const playSpeed = ref(100)
// 进度
const percentage = ref(0)
const currentPosition = ref<{ [key: string]: any }>()
const polylinePath = ref([])
let stepInterval: any = null
const currentStep = ref(0)
const isPlay = ref(false)
const speed = ref(0)
// watch(
//   () => gpsTrackState.value,
//   (value) => {
//     // console.log(value)
//     if (value) {
//       nextTick(() => {
//         demo = ElLoading.service({
//           target: '.demo',
//           text: '生成数据中...',
//           background: 'rgba(255,255,255,0.7)'
//         })
//       })
//     } else {
//       demo?.close()
//     }
//   },
//   {
//     immediate: true
//   }
// )
// watch(
//   () => gpsTrackData.value,
//   (value) => {
//     console.log('gpsTrackData变化', value)
//     resetData(value)
//     handleRefresh()
//   }
// )
// watch(
//   () => curPos.value,
//   (value) => {
//     currentStep.value = value
//     adjust()
//   }
// )
const currentPage = computed(() => {
  return (record.position.length > 0 ? currentStep.value + 1 : 0) + ' / ' + record.position.length
})

onBeforeUnmount(() => {
  clearInterval(stepInterval)
})

onMounted(() => {
  initMap()
})

onUnmounted(() => {
  // gpsbus.off('WS_CMD_POSITIONS', positionsCome)
})

/**
 * 初始化地图
 * @param options
 */
function initMap(options?: number[]) {
  console.log('initMap track')
  openMap.value = createMap('map-trajectory', createLayers2())
  // browserLocal()
  //   .then((pos) => {
  //     openMap.getView().animate({
  //       center: [pos.lng, pos.lat],
  //       duration: 100
  //     })
  //   })
  //   .catch((e) => {
  //     console.log(e)
  //   })
}

/**
 * 获取数据
 */
function resetData(data: any) {
  const { positions, stops } = data
  record.position = []
  record.stopPosition = []
  record.travelPath = []
  if (stops?.length) {
    record.stopPosition = stops.map((item: any) => {
      const { lng, lat } = wsg2mapcoor(item.longitude, item.latitude)
      return {
        lng,
        lat,
        time: timeFormat(item.duration)
      }
    })
  }

  if (vectorLayer.value) {
    openMap.value?.removeLayer(vectorLayer.value)
  }
  if (iconLayer.value) {
    openMap.value?.removeLayer(iconLayer.value)
  }
  if (positions?.length) {
    record.position = positions

    currentPosition.value = positions[0]

    record.travelPath = positions.map((item: any) => {
      const { lng, lat } = wsg2mapcoor(item.longitude, item.latitude)
      return [lng, lat]
    })
    trajectoryPath(record.travelPath)
  }
}

/**
 * 画轨迹
 * @param e
 */
function trajectoryPath(e: any[]) {
  const polyline = e
  // 实例化图层
  let geometry = new LineString(polyline)
  let source = new sourceVector()
  // 绘制轨迹
  let LineFeature = new Feature(geometry)
  source.addFeature(LineFeature)
  vectorLayer.value = new layerVector({
    source,
    style: new Style({
      fill: new Fill({
        color: 'rgba(255, 255, 255, 0.6)'
      }),
      stroke: new Stroke({
        color: 'rgba(20, 155, 155, 0.8)',
        width: 6
      }),
      image: new Circle({
        radius: 7,
        fill: new Fill({
          color: '#0099FF'
        })
      })
    })
  })
  openMap.value?.addLayer(vectorLayer.value)
  setMark(polyline)
}

/**
 * 画Marker点
 * @param e
 */
function setMark(e: any[]) {
  let markers: any[] = [
    {
      po: e[0],
      key: startIconPng,
      name: 'start'
    },
    {
      po: e[e.length - 1],
      key: endIconPng,
      name: 'end'
    }
  ]
  if (record.stopPosition.length > 0) {
    markers.push(
      ...record.stopPosition.map((item: any) => {
        // console.log('stopPosition', item)
        return {
          po: [item.lng, item.lat],
          key: stopCar,
          name: 'stop',
          time: item.time
        }
      })
    )
  }
  let isIcon: any[] = []
  markers.forEach((item: any) => {
    // 创建图标特性
    let iconFeature = new Feature({
      geometry: new Point(item.po),
      name: item.name
    })
    // 创建图标样式
    iconFeature.setStyle(
      new Style({
        image: new Icon({
          // 定义图标锚点
          anchor: [12, 0.5],
          anchorOrigin: 'bottom-left',
          anchorXUnits: 'pixels',
          anchorYUnits: 'pixels',
          src: item.key
        }),
        text:
          item.name === 'stop'
            ? new Text({
                font: '13px sans-serif',
                offsetX: 0,
                offsetY: -50,
                textAlign: 'center',
                textBaseline: 'middle',
                text: `停留时间：${item.time}`,
                backgroundFill: new Fill({
                  color: 'rgba(128,134,149, 0.8)'
                }),
                fill: new Fill({
                  color: '#fff'
                }),
                padding: [4, 5, 4, 5]
              })
            : undefined
      })
    )
    isIcon.push(iconFeature)
  })
  let vectorSource = new sourceVector({
    features: isIcon
  })
  // 图标添加进矢量容器
  carSource.value = vectorSource
  // 创建矢量图层
  iconLayer.value = new layerVector({
    source: vectorSource
  })
  openMap.value?.addLayer(iconLayer.value)
  // 绘制车表
  timeMarker([record.position[0].longitude, record.position[0].latitude], 0, false)
  // 定位地图总心
  openMap.value?.getView().setCenter(e[0])
  // console.log('end')
}

/**
 * 遍历
 * @param v
 * @param rotation
 * @param status
 */
function timeMarker(v: any[], rotation: number, status: boolean) {
  if (status) {
    carSource.value.removeFeature(carFeature)
  }
  const { lng, lat } = wsg2mapcoor(v[0], v[1])
  carFeature = new Feature({
    geometry: new Point([lng, lat])
  })
  carFeature.setStyle(
    new Style({
      image: new Icon({
        // 定义图标锚点
        anchor: [10, 18],
        anchorOrigin: 'bottom-left',
        anchorXUnits: 'pixels',
        anchorYUnits: 'pixels',
        rotation: (Math.PI / 180) * (rotation % 360),
        src: carbluePng
      })
    })
  )
  carSource.value.addFeature(carFeature)
}

/**
 * 判断小车是否在可视范围内
 * @param lat
 * @param lng
 */
function isInside(lat: number, lng: number) {
  let isArr: any = openMap.value?.getView().calculateExtent(openMap.value?.getSize())
  if (
    !IsPtInPoly(lat, lng, [
      { longitude: isArr[2], latitude: isArr[1] },
      { longitude: isArr[0], latitude: isArr[1] },
      { longitude: isArr[0], latitude: isArr[3] },
      { longitude: isArr[2], latitude: isArr[3] }
    ])
  ) {
    openMap.value?.getView().setCenter([lng, lat])
  }
}

/**
 * 开始播放
 */
function handlePlay() {
  if (record.position.length === 0) {
    return ElMessage.warning('无法播放')
  }
  stepInterval = setInterval(() => {
    if (currentStep.value < record.position.length - 1) {
      isPlay.value = true
      currentStep.value++
      // currentPosition.value = record.position[currentStep.value]
      // timeMarker([currentPosition.value?.longitude, currentPosition.value?.latitude], currentPosition.value?.course, true)
      // isInside(currentPosition.value?.latitude, currentPosition.value?.longitude)
      // speed.value = record.position[currentStep.value].speed
      // percentage.value = parseFloat(((currentStep.value / record.position.length) * 100).toFixed(1))
      adjust()
    } else {
      percentage.value = 100
      handlePause()
    }
  }, playSpeed.value)
}

/**
 * 暂停播放
 */
function handlePause() {
  isPlay.value = false
  clearInterval(stepInterval)
}

/**
 * 重置播放
 */
function handleRefresh() {
  currentStep.value = 0
  percentage.value = 0
  currentPosition.value = record.position[0]
  polylinePath.value.splice(0, polylinePath.value.length)
}

/**
 * 上一步
 */
function handlePrev() {
  if (currentStep.value > 0) {
    currentStep.value--
  }
  polylinePath.value.splice(currentStep.value, polylinePath.value.length)
  adjust()
}

/**
 * 下一步
 */
function handleNext() {
  if (currentStep.value < record.position.length - 1) {
    currentStep.value++
  }
  adjust()
}
function adjust() {
  const pos = record.position[currentStep.value]
  currentPosition.value = pos
  // 获取速度表
  speed.value = pos?.speed
  // 获取百分比
  percentage.value = parseFloat(((currentStep.value / record.position.length) * 100).toFixed(1))
  const rotation = pos?.course
  timeMarker([pos.longitude, pos.latitude], rotation, true)
  isInside(pos?.latitude, pos?.longitude)
}
/**
 * 暴露数据和方法
 */
// defineExpose({
// })
</script>

<template>
  <div class="demo">
    <div id="map-track" class="map-track"></div>
    <!-- <div class="mapType">
      <el-dropdown @command="mapTypeChange">
        <span class="el-dropdown-link"> 切换地图 </span>
        <template #dropdown>
          <el-dropdown-menu>
            <el-dropdown-item v-for="item in mapType" :key="item.id" :command="item.id">{{ item.name }}</el-dropdown-item>
          </el-dropdown-menu>
        </template>
      </el-dropdown>
    </div> -->
    <ElCard
      v-if="props.control"
      class="tool-window"
      :style="{ width: '400px', position: 'absolute', bottom: '-10px', right: 0, background: 'rgba(255,255,255,0.7)', border: 'none' }"
      :body-style="{}">
      <!-- <ElDatePicker v-model="dateRange" type="daterange" value-format="YYYY-MM-DD"> </ElDatePicker> -->
      <div style="margin: 20px 0">
        播放速度
        <ElInputNumber v-model="playSpeed" :precision="0" :min="100" :max="5000" step-strictly :step="100" style="width: 150px"></ElInputNumber>
        毫秒
      </div>
      <ElProgress :text-inside="true" :stroke-width="15" :percentage="percentage"></ElProgress>
      <div style="margin: 10px 0">轨迹时间：{{ currentPosition?.deviceTime }}</div>
      <div style="margin-bottom: 10px">运动速度：{{ (speed * 1.852).toFixed(2) }} Km/h</div>
      <div class="control">
        <ElButton v-if="!isPlay" type="primary" :icon="VideoPlay" @click="handlePlay"></ElButton>
        <ElButton v-else type="primary" :icon="VideoPause" @click="handlePause"></ElButton>
        <ElButton type="danger" :icon="Refresh" @click="handleRefresh"></ElButton>
        <el-button type="success" class="button" :disabled="currentStep === 0" :icon="DArrowLeft" @click="handlePrev"></el-button>
        <span class="pageNum">{{ currentPage }}</span>
        <el-button
          type="success"
          class="button"
          :disabled="currentStep === record.position.length - 1 || record.position.length === 0"
          :icon="DArrowRight"
          @click="handleNext"></el-button>
      </div>
    </ElCard>
  </div>
</template>

<style scoped lang="css">
.demo {
  position: relative;
  width: 100%;
  height: 100%;
}
.map-track {
  flex: 1;
  height: 100%;
}
.mapType {
  position: absolute;
  top: 20px;
  right: 20px;
  z-index: 99;
}

.control {
  display: flex;
  margin-top: 20px;
}
.pageNum {
  display: inline-block;
  font-size: 20px;
  transform: translateY(5px);
  margin: 0 5px;
}
</style>
